package com.xd.user.controller;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xd.common.base.BaseController;
import com.xd.common.model.R;
import com.xd.common.security.util.SecurityUtils;
import com.xd.user.api.entity.*;
import com.xd.user.api.feign.UserFeign;
import com.xd.user.service.*;
import io.swagger.annotations.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户(User)表控制层
 *
 * @author hbx
 * @since 2019-12-30 17:17:28
 */
@Slf4j
@RestController
@RequestMapping("user")
@Api
@Transactional(rollbackFor = Exception.class)
public class UserController extends BaseController<UserService, User, String> implements UserFeign {

    @Resource
    private UserService userService;

    @Resource
    private DepartmentService departmentService;

    @Resource
    private DepartmentHeaderService departmentHeaderService;

    @Resource
    private UserRoleService userRoleService;
    @Resource
    private RoleService roleService;
    @Resource
    private PermissionService permissionService;


    /**
     * 根据用户名获取用户
     *
     * @param username 用户名
     * @return 用户信息
     */
    @PostMapping("/login")
    @Override
    public R<User> login(@RequestParam String username) {
        User one = userService.getOne(Wrappers
                .<User>lambdaQuery().eq(User::getUsername, username));
        if (!ObjectUtil.isEmpty(one)) {
            List<Role> byUserId = userRoleService.findByUserId(one.getId());
            List<String> collect = byUserId.stream()
                    .map(Role::getId)
                    .collect(Collectors.toList());
            if (!ObjectUtil.isEmpty(collect)) {
                List<Role> list = roleService.list(Wrappers.<Role>lambdaQuery().in(Role::getId, collect));
                one.setRoles(list);
                List<Permission> permissions = permissionService.listByUserId(one.getId());
                one.setPermissions(permissions);
            }
        }
        return success(one);
    }


    /**
     * @param departmentId 部门id
     * @return com.baomidou.mybatisplus.extension.api.R<java.util.List < com.xd.user.api.entity.User>>
     * @author huboxin
     * @description: TODO 查询部门下的员工
     * @date 8:55 2020/7/1
     **/
    @ApiOperation(value = "查询部门下的员工", notes = "查询部门下的员工")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "departmentId", value = "部门id"),
    })
    @GetMapping("listByDepartmentId/{departmentId}")
    @Override
    public R<List<User>> listByDepartmentId(@PathVariable String departmentId) {
        List<String> userIds = departmentHeaderService.listObjs(Wrappers.<DepartmentHeader>lambdaQuery()
                .select(DepartmentHeader::getUserId)
                .eq(DepartmentHeader::getDepartmentId, departmentId), Object::toString);
        if (ObjectUtil.isEmpty(userIds)) {
            return success(new ArrayList<>());
        }
        List<User> list = userService.list(Wrappers.<User>lambdaQuery().in(User::getId, userIds));
        return success(list);
    }


    /**
     * @return R<ModelUser>
     * @author huboxin
     * @description: 获取用户详细信息
     * @date 8:55 2020/7/1
     **/
    @ApiOperation(value = "获取用户详细信息", notes = "获取用户详细信息")
    @GetMapping("getUserInfo")
    public R<User> getUserInfo() {
        return success(SecurityUtils.getUser());
    }

    /**
     * @param page 分页
     * @return com.baomidou.mybatisplus.extension.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.xd.user.api.entity.User>>
     * @author huboxin
     * @description: 分页按条件查询用户
     * @date 14:58 2020/6/28
     **/
    @PostMapping("selectAllByPage")
    @ApiOperation(value = "分页按条件查询用户", notes = "分页按条件查询用户")
    public R<IPage<User>> selectAllByPage(@RequestBody @ApiParam("分页") Page<User> page) {
        IPage<User> page1 = this.service.page(page);
        List<User> records = page1.getRecords();
        records.forEach(user -> {
            user.setPassword(null);
            Department byId = departmentService.getById(user.getDepartmentId());
            user.setDepartmentTitle(ObjectUtil.isEmpty(byId) ? "" : byId.getTitle());
            List<Role> roles = userRoleService.findByUserId(user.getId());
            user.setRoles(roles);
        });
        return success(page1);
    }


    /**
     * @param user 用户信息
     * @return com.baomidou.mybatisplus.extension.api.R<java.lang.Boolean>
     * @author huboxin
     * @description: TODO 添加或修改用户
     * @date 14:12 2020/7/3
     **/
    @PostMapping("saveOrUpdate")
    @ApiOperation(value = "添加或修改用户", notes = "添加或修改用户")
    public R<Boolean> saveOrUpdate(@RequestBody @ApiParam("用户信息") User user) {
        //判断用户名不可重复
        List<User> list = userService.list(Wrappers.<User>lambdaQuery()
                .eq(User::getUsername, user.getUsername())
                .ne(!ObjectUtil.isEmpty(user.getId()), User::getId, user.getId())
        );
        if (!ObjectUtil.isEmpty(list)) {
            return failed("用户名已存在");
        }

        //密码加密
        user.setPassword(ObjectUtil.isEmpty(user.getPassword()) ? null : new BCryptPasswordEncoder().encode(user.getPassword()));
        boolean saveOrUpdate = userService.saveOrUpdate(user);
        if(!saveOrUpdate){
            return failed("操作用户失败");
        }

        //添加用户角色关联
        if (CollUtil.isNotEmpty(user.getRoles())) {
            userRoleService.remove(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, user.getId()));
            log.warn("清除用户与角色关联数据");
            List<UserRole> collect = user.getRoles()
                    .stream()
                    .map(role -> ObjectUtil.isEmpty(role.getId()) ? null : new UserRole().setRoleId(role.getId())
                            .setUserId(user.getId()))
                    .filter(ObjectUtil::isNotEmpty)
                    .collect(Collectors.toList());
            userRoleService.saveBatch(collect);
            log.warn("重新添加用户与角色关联数据");
        }
        return success(true) ;
    }

}
